home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 3_1_3 / src / priest.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-08  |  17.1 KB  |  669 lines

  1. /*    SCCS Id: @(#)priest.c    3.1    93/05/15    */
  2. /* Copyright (c) Izchak Miller, Steve Linhart, 1989.           */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include "mfndpos.h"
  7. #include "eshk.h"
  8. #include "epri.h"
  9. #include "emin.h"
  10.  
  11. #ifdef OVLB
  12.  
  13. static boolean FDECL(histemple_at,(struct monst *,XCHAR_P,XCHAR_P));
  14. static boolean FDECL(has_shrine,(struct monst *));
  15.  
  16. /*
  17.  * Move for priests and shopkeepers.  Called from shk_move() and pri_move().
  18.  * Valid returns are  1: moved  0: didn't  -1: let m_move do it  -2: died.
  19.  */
  20. int
  21. move_special(mtmp,in_his_shop,appr,uondoor,avoid,omx,omy,gx,gy)
  22. register struct monst *mtmp;
  23. boolean in_his_shop;
  24. schar appr;
  25. boolean uondoor,avoid;
  26. register xchar omx,omy,gx,gy;
  27. {
  28.     register xchar nx,ny,nix,niy;
  29.     register schar i;
  30.     schar chcnt,cnt;
  31.     coord poss[9];
  32.     long info[9];
  33.     long allowflags;
  34.     struct obj *ib = (struct obj *)0;
  35.  
  36.     if(omx == gx && omy == gy)
  37.         return(0);
  38.     if(mtmp->mconf) {
  39.         avoid = FALSE;
  40.         appr = 0;
  41.     }
  42.  
  43.     nix = omx;
  44.     niy = omy;
  45.     if (mtmp->isshk) allowflags = ALLOW_SSM;
  46.     else allowflags = ALLOW_SSM | ALLOW_SANCT;
  47.     if (passes_walls(mtmp->data)) allowflags |= (ALLOW_ROCK|ALLOW_WALL);
  48.     if (throws_rocks(mtmp->data)) allowflags |= ALLOW_ROCK;
  49.     if (tunnels(mtmp->data) &&
  50.             (!needspick(mtmp->data) || m_carrying(mtmp, PICK_AXE)))
  51.         allowflags |= ALLOW_DIG;
  52.     if (!nohands(mtmp->data) && !verysmall(mtmp->data)) {
  53.         allowflags |= OPENDOOR;
  54.         if (m_carrying(mtmp, SKELETON_KEY)) allowflags |= BUSTDOOR;
  55.     }
  56.     if (is_giant(mtmp->data)) allowflags |= BUSTDOOR;
  57.     cnt = mfndpos(mtmp, poss, info, allowflags);
  58.  
  59.     if(mtmp->isshk && avoid && uondoor) { /* perhaps we cannot avoid him */
  60.         for(i=0; i<cnt; i++)
  61.             if(!(info[i] & NOTONL)) goto pick_move;
  62.         avoid = FALSE;
  63.     }
  64.  
  65. #define    GDIST(x,y)    (dist2(x,y,gx,gy))
  66. pick_move:
  67.     chcnt = 0;
  68.     for(i=0; i<cnt; i++) {
  69.         nx = poss[i].x;
  70.         ny = poss[i].y;
  71.         if(levl[nx][ny].typ == ROOM ||
  72.             (mtmp->ispriest &&
  73.                 levl[nx][ny].typ == ALTAR) ||
  74.             (mtmp->isshk &&
  75.                 (!in_his_shop || ESHK(mtmp)->following))) {
  76.             if(avoid && (info[i] & NOTONL))
  77.             continue;
  78.             if((!appr && !rn2(++chcnt)) ||
  79.             (appr && GDIST(nx,ny) < GDIST(nix,niy))) {
  80.                 nix = nx;
  81.                 niy = ny;
  82.             }
  83.         }
  84.     }
  85.     if(mtmp->ispriest && avoid &&
  86.             nix == omx && niy == omy && onlineu(omx,omy)) {
  87.         /* might as well move closer as long it's going to stay
  88.          * lined up */
  89.         avoid = FALSE;
  90.         goto pick_move;
  91.     }
  92.  
  93.     if(nix != omx || niy != omy) {
  94.         remove_monster(omx, omy);
  95.         place_monster(mtmp, nix, niy);
  96.         newsym(nix,niy);
  97.         if (mtmp->isshk && !in_his_shop && inhishop(mtmp))
  98.             check_special_room(FALSE);
  99.         if(ib) {
  100.             if (cansee(mtmp->mx,mtmp->my))
  101.                 pline("%s picks up %s.", Monnam(mtmp),
  102.                 distant_name(ib,doname));
  103.             freeobj(ib);
  104.             mpickobj(mtmp, ib);
  105.         }
  106.         return(1);
  107.     }
  108.     return(0);
  109. }
  110.  
  111. #endif /* OVLB */
  112.  
  113. #ifdef OVL0
  114.  
  115. char
  116. temple_occupied(array)
  117. register char *array;
  118. {
  119.     register char *ptr;
  120.  
  121.     for (ptr = array; *ptr; ptr++)
  122.         if (rooms[*ptr - ROOMOFFSET].rtype == TEMPLE)
  123.             return(*ptr);
  124.     return('\0');
  125. }
  126.  
  127. #endif /* OVL0 */
  128. #ifdef OVLB
  129.  
  130. static boolean
  131. histemple_at(priest, x, y)
  132. register struct monst *priest;
  133. register xchar x, y;
  134. {
  135.     return((boolean)((EPRI(priest)->shroom == *in_rooms(x, y, TEMPLE)) &&
  136.            on_level(&(EPRI(priest)->shrlevel), &u.uz)));
  137. }
  138.  
  139. /*
  140.  * pri_move: return 1: moved  0: didn't  -1: let m_move do it  -2: died
  141.  */
  142. int
  143. pri_move(priest)
  144. register struct monst *priest;
  145. {
  146.     register xchar gx,gy,omx,omy;
  147.     schar temple;
  148.     boolean avoid = TRUE;
  149.  
  150.     omx = priest->mx;
  151.     omy = priest->my;
  152.  
  153.     if(!histemple_at(priest, omx, omy)) return(-1);
  154.  
  155.     temple = EPRI(priest)->shroom;
  156.  
  157.     gx = EPRI(priest)->shrpos.x;
  158.     gy = EPRI(priest)->shrpos.y;
  159.  
  160.     gx += rn1(3,-1);    /* mill around the altar */
  161.     gy += rn1(3,-1);
  162.  
  163.     if(!priest->mpeaceful ||
  164.        (Conflict && !resist(priest, RING_CLASS, 0, 0))) {
  165.         if(monnear(priest, u.ux, u.uy)) {
  166.             if(Displaced)
  167.                 Your("displaced image doesn't fool %s!",
  168.                     mon_nam(priest));
  169.             (void) mattacku(priest);
  170.             return(0);
  171.         } else if(index(u.urooms, temple)) {
  172.             /* chase player if inside temple & can see him */
  173.             if(priest->mcansee && m_canseeu(priest)) {
  174.                 gx = u.ux;
  175.                 gy = u.uy;
  176.             }
  177.             avoid = FALSE;
  178.         }
  179.     } else if(Invis) avoid = FALSE;
  180.  
  181.     return(move_special(priest,FALSE,TRUE,FALSE,avoid,omx,omy,gx,gy));
  182. }
  183.  
  184. /* exclusively for mktemple() */
  185. void
  186. priestini(lvl, sroom, sx, sy, sanctum)
  187. d_level    *lvl;
  188. struct mkroom *sroom;
  189. int sx, sy;
  190. boolean sanctum;   /* is it the seat of the high priest? */
  191. {
  192.     register struct monst *priest;
  193.     register struct obj *otmp;
  194.     register int cnt;
  195.  
  196.     if(MON_AT(sx+1, sy))
  197.         rloc(m_at(sx+1, sy)); /* insurance */
  198.  
  199.     priest = (sanctum ? makemon(&mons[PM_HIGH_PRIEST], sx+1, sy)
  200.               : makemon(&mons[PM_ALIGNED_PRIEST], sx+1, sy));
  201.     if (priest) {
  202.         EPRI(priest)->shroom = (sroom - rooms) + ROOMOFFSET;
  203.         EPRI(priest)->shralign = Amask2align(levl[sx][sy].altarmask);
  204.         EPRI(priest)->shrpos.x = sx;
  205.         EPRI(priest)->shrpos.y = sy;
  206.         assign_level(&(EPRI(priest)->shrlevel), lvl);
  207.         priest->mtrapseen = ~0;    /* traps are known */
  208.         priest->mpeaceful = 1;
  209.         priest->ispriest = 1;
  210.         priest->msleep = 0;
  211.         set_malign(priest); /* mpeaceful may have changed */
  212.  
  213.         /* now his/her goodies... */
  214.         (void) mongets(priest, CHAIN_MAIL);
  215.         (void) mongets(priest, SMALL_SHIELD);
  216. #ifdef MUSE
  217.         m_dowear(priest, TRUE);
  218. #endif
  219.         priest->mgold = (long)rn1(10,20);
  220.         if(sanctum && EPRI(priest)->shralign == A_NONE &&
  221.              on_level(&sanctum_level, &u.uz))
  222.             (void) mongets(priest, AMULET_OF_YENDOR);
  223.         /* Do NOT put the rest in m_initinv.    */
  224.         /* Priests created elsewhere than in a  */
  225.         /* temple should not carry these items, */
  226.         /* except for the mace.            */
  227.         cnt = rn1(2,3);
  228.         while(cnt) {
  229.             otmp = mkobj(SPBOOK_CLASS, FALSE);
  230.             if(otmp) mpickobj(priest, otmp);
  231.             cnt--;
  232.         }
  233.         if(p_coaligned(priest))
  234.             (void) mongets(priest, rn2(2) ? CLOAK_OF_PROTECTION
  235.                           : CLOAK_OF_MAGIC_RESISTANCE);
  236.         else {
  237.             if(!rn2(5))
  238.             otmp = mksobj(CLOAK_OF_MAGIC_RESISTANCE, TRUE, FALSE);
  239.             else otmp = mksobj(CLOAK_OF_PROTECTION, TRUE, FALSE);
  240.             if(otmp) {
  241.             if(!rn2(2)) curse(otmp);
  242.             mpickobj(priest, otmp);
  243.             }
  244.         }
  245.  
  246.         otmp = mksobj(MACE, FALSE, FALSE);
  247.         if(otmp) {
  248.             otmp->spe = rnd(3);
  249.             if(!rn2(2)) curse(otmp);
  250.             mpickobj(priest, otmp);
  251.         }
  252.     }
  253. }
  254.  
  255. /*
  256.  * Specially aligned monsters are named specially.
  257.  *    - aligned priests with ispriest and high priests have shrines
  258.  *        they retain ispriest and epri when polymorphed
  259.  *    - aligned priests without ispriest and Angels are roamers
  260.  *        they retain isminion and access epri as emin when polymorphed
  261.  *        (coaligned Angels are also created as minions, but they
  262.  *        use the same naming convention)
  263.  *    - minions do not have ispriest but have isminion and emin
  264.  */
  265. char *
  266. priestname(mon)
  267. register struct monst *mon;
  268. {
  269.     static NEARDATA char pname[PL_NSIZ];
  270.  
  271.     Strcpy(pname, "the ");
  272.     if (mon->minvis) Strcat(pname, "invisible ");
  273.     if (mon->ispriest || mon->data == &mons[PM_ALIGNED_PRIEST] ||
  274.                     mon->data == &mons[PM_ANGEL]) {
  275.         /* use epri */
  276.         if (mon->mtame && mon->data == &mons[PM_ANGEL])
  277.             Strcat(pname, "guardian ");
  278.         if (mon->data != &mons[PM_ALIGNED_PRIEST] &&
  279.                 mon->data != &mons[PM_HIGH_PRIEST]) {
  280.             Strcat(pname, mon->data->mname);
  281.             Strcat(pname, " ");
  282.         }
  283.         if (mon->data != &mons[PM_ANGEL]) {
  284.             if (!mon->ispriest && EPRI(mon)->renegade)
  285.                 Strcat(pname, "renegade ");
  286.             if (mon->data == &mons[PM_HIGH_PRIEST])
  287.                 Strcat(pname, "high ");
  288.             if (mon->female)
  289.                 Strcat(pname, "priestess ");
  290.             else
  291.                 Strcat(pname, "priest ");
  292.         }
  293.         Strcat(pname, "of ");
  294.         Strcat(pname, align_gname((int)EPRI(mon)->shralign));
  295.         return(pname);
  296.     }
  297.     /* use emin instead of epri */
  298.     Strcat(pname, mon->data->mname);
  299.     Strcat(pname, " of ");
  300.     Strcat(pname, align_gname(EMIN(mon)->min_align));
  301.     return(pname);
  302. }
  303.  
  304. boolean
  305. p_coaligned(priest)
  306. struct monst *priest;
  307. {
  308.     return((boolean)(u.ualign.type == ((int)EPRI(priest)->shralign)));
  309. }
  310.  
  311. static boolean
  312. has_shrine(pri)
  313. struct monst *pri;
  314. {
  315.     struct rm *lev;
  316.  
  317.     if(!pri)
  318.         return(FALSE);
  319.     lev = &levl[EPRI(pri)->shrpos.x][EPRI(pri)->shrpos.y];
  320.     if (!IS_ALTAR(lev->typ) || !(lev->altarmask & AM_SHRINE))
  321.         return(FALSE);
  322.     return((boolean)(EPRI(pri)->shralign == Amask2align(lev->altarmask & ~AM_SHRINE)));
  323. }
  324.  
  325. struct monst *
  326. findpriest(roomno)
  327. char roomno;
  328. {
  329.     register struct monst *mtmp;
  330.     extern struct monst *fdmon; /* from mon.c */
  331.  
  332.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  333.         if(mtmp->ispriest && (EPRI(mtmp)->shroom == roomno) &&
  334.            histemple_at(mtmp,mtmp->mx,mtmp->my))
  335.         return(mtmp);
  336.     for(mtmp = fdmon; mtmp; mtmp = mtmp->nmon)
  337.         if(mtmp->ispriest && (EPRI(mtmp)->shroom == roomno) &&
  338.            histemple_at(mtmp,mtmp->mx,mtmp->my))
  339.         return(mtmp);
  340.     return (struct monst *)0;
  341. }
  342.  
  343. /* called from check_special_room() when the player enters the temple room */
  344. void
  345. intemple(roomno)
  346. register int roomno;
  347. {
  348.     register struct monst *priest = findpriest((char)roomno);
  349.     boolean tended = (priest != (struct monst *)0);
  350.     boolean shrined = (tended && has_shrine(priest));
  351.     boolean sanctum = (tended && priest->data == &mons[PM_HIGH_PRIEST] &&
  352.                 (Is_sanctum(&u.uz) || In_endgame(&u.uz)));
  353.  
  354.     if(!temple_occupied(u.urooms0)) {
  355.         if(tended) {
  356.         pline("%s intones:",
  357.               (!Blind ? Monnam(priest) : "A nearby voice"));
  358.         if(sanctum && Is_sanctum(&u.uz)) {
  359.             if(priest->mpeaceful) {
  360.               verbalize("Infidel, you entered Moloch's Sanctum!");
  361.               verbalize("Be gone!");
  362.               priest->mpeaceful = 0;
  363.               set_malign(priest);
  364.             } else
  365.               verbalize("You desecrate this place by your presence!");
  366.         } else verbalize("Pilgrim, you enter a%s place!",
  367.                !shrined ? " desecrated" :
  368.                " sacred");
  369.         if(!sanctum) {
  370.             /* !tended -> !shrined */
  371.             if(!shrined || !p_coaligned(priest) ||
  372.                            u.ualign.record < -5)
  373.             You("have a%s forbidding feeling...",
  374.                 (!shrined) ? "" : " strange");
  375.             else You("experience a strange sense of peace.");
  376.         }
  377.         } else {
  378.         switch(rn2(3)) {
  379.           case 0: You("have an eerie feeling..."); break;
  380.           case 1: You("feel like you are being watched."); break;
  381.           default: pline("A shiver runs down your %s.",
  382.             body_part(SPINE)); break;
  383.         }
  384.         if(!rn2(5)) {
  385.             struct monst *mtmp;
  386.  
  387.             if(!(mtmp = makemon(&mons[PM_GHOST],u.ux,u.uy))) return;
  388.             pline("An enormous ghost appears next to you!");
  389.             mtmp->mpeaceful = 0;
  390.             set_malign(mtmp);
  391.             if(flags.verbose)
  392.             You("are frightened to death, and unable to move.");
  393.             nomul(-3);
  394.             nomovemsg = "You regain your composure.";
  395.            }
  396.        }
  397.        }
  398. }
  399.  
  400. void
  401. priest_talk(priest)
  402. register struct monst *priest;
  403. {
  404.     boolean coaligned = p_coaligned(priest);
  405.     boolean strayed = (u.ualign.record < 0);
  406.  
  407.     if(priest->mflee || (!priest->ispriest && coaligned && strayed)) {
  408.         pline("%s doesn't want anything to do with you!",
  409.                 Monnam(priest));
  410.         priest->mpeaceful = 0;
  411.         return;
  412.     }
  413.  
  414.     /* priests don't chat unless peaceful and in their own temple */
  415.     if(!histemple_at(priest,priest->mx,priest->my) ||
  416.          !priest->mpeaceful || !priest->mcanmove || priest->msleep) {
  417.         if(!priest->mcanmove || priest->msleep) {
  418.         pline("%s breaks out of %s reverie!",
  419.               Monnam(priest), his[pronoun_gender(priest)]);
  420.         priest->mfrozen = priest->msleep = 0;
  421.         priest->mcanmove = 1;
  422.         }
  423.         priest->mpeaceful = 0;
  424.         switch(rn2(3)) {
  425.         case 0:
  426.            verbalize("Thou wouldst have words, eh?  I'll give thee a word or two!");
  427.            break;
  428.         case 1:
  429.            verbalize("Talk?  Here is what I have to say!");
  430.            break;
  431.         default:
  432.            verbalize("Pilgrim, I would speak no longer with thee.");
  433.            break;
  434.         }
  435.         return;
  436.     }
  437.  
  438.     /* you desecrated the temple and now you want to chat? */
  439.     if(priest->mpeaceful && *in_rooms(priest->mx, priest->my, TEMPLE) &&
  440.           !has_shrine(priest)) {
  441.         verbalize("Begone!  Thou desecratest this holy place with thy presence.");
  442.         priest->mpeaceful = 0;
  443.         return;
  444.     }
  445.  
  446.     if(!u.ugold) {
  447.         if(coaligned && !strayed) {
  448.         if (priest->mgold > 0L) {
  449.             /* Note: two bits is actually 25 cents.  Hmm. */
  450.             pline("%s gives you %s for an ale.", Monnam(priest),
  451.             (priest->mgold == 1L) ? "one bit" : "two bits");
  452.             if (priest->mgold > 1L)
  453.             u.ugold = 2L;
  454.             else
  455.             u.ugold = 1L;
  456.             priest->mgold -= u.ugold;
  457.             flags.botl = 1;
  458.         } else
  459.             pline("%s preaches the virtues of poverty.", Monnam(priest));
  460.         exercise(A_WIS, TRUE);
  461.         } else
  462.         pline("%s is not interested.", Monnam(priest));
  463.         return;
  464.     } else {
  465.         long offer;
  466.  
  467.         pline("%s asks you for a contribution for the temple.",
  468.             Monnam(priest));
  469.         if((offer = bribe(priest)) == 0) {
  470.         verbalize("Thou shalt regret thine action!");
  471.         if(coaligned) u.ualign.record--;
  472.         } else if(offer < (u.ulevel * 200)) {
  473.         if(u.ugold > (offer * 2L)) verbalize("Cheapskate.");
  474.         else {
  475.             verbalize("I thank thee for thy contribution.");
  476.             /*  give player some token  */
  477.             exercise(A_WIS, TRUE);
  478.         }
  479.         } else if(offer < (u.ulevel * 400)) {
  480.         verbalize("Thou art indeed a pious individual.");
  481.         if(u.ugold < (offer * 2L)) {
  482.             if(coaligned && u.ualign.record < -5) u.ualign.record++;
  483.             verbalize("I bestow upon thee a blessing.");
  484.             Clairvoyant += rn1(500,500);
  485.         }
  486.         } else if(offer < (u.ulevel * 600) &&
  487.               u.ublessed < 20 &&
  488.               (u.ublessed < 9 || !rn2(u.ublessed))) {
  489.         verbalize("Thy devotion has been rewarded.");
  490.         if (!(Protection & INTRINSIC))  {
  491.             Protection |= FROMOUTSIDE;
  492.             if (!u.ublessed)  u.ublessed = rn1(3, 2);
  493.         } else u.ublessed++;
  494.         } else {
  495.         verbalize("Thy selfless generosity is deeply appreciated.");
  496.         if(u.ugold < (offer * 2L) && coaligned) {
  497.             if(strayed && (moves - u.ucleansed) > 5000L) {
  498.             u.ualign.record = 0; /* cleanse thee */
  499.             u.ucleansed = moves;
  500.             } else {
  501.             u.ualign.record += 2;
  502.             }
  503.         }
  504.         }
  505.     }
  506. }
  507.  
  508. struct monst *
  509. mk_roamer(ptr, alignment, x, y, peaceful)
  510. register struct permonst *ptr;
  511. aligntyp alignment;
  512. xchar x, y;
  513. boolean peaceful;
  514. {
  515.     register struct monst *roamer;
  516.     register boolean coaligned = (u.ualign.type == alignment);
  517.  
  518.     if (ptr != &mons[PM_ALIGNED_PRIEST] && ptr != &mons[PM_ANGEL])
  519.         return((struct monst *)0);
  520.     
  521.     if (MON_AT(x, y)) rloc(m_at(x, y));    /* insurance */
  522.  
  523.     if (!(roamer = makemon(ptr, x, y)))
  524.         return((struct monst *)0);
  525.  
  526.     EPRI(roamer)->shralign = alignment;
  527.     if (coaligned && !peaceful)
  528.         EPRI(roamer)->renegade = TRUE;
  529.     /* roamer->ispriest == FALSE naturally */
  530.     roamer->isminion = TRUE;    /* borrowing this bit */
  531.     roamer->mtrapseen = ~0;        /* traps are known */
  532.     roamer->mpeaceful = peaceful;
  533.     roamer->msleep = 0;
  534.     set_malign(roamer); /* peaceful may have changed */
  535.  
  536.     /* MORE TO COME */
  537.     return(roamer);
  538. }
  539.  
  540. void
  541. reset_hostility(roamer)
  542. register struct monst *roamer;
  543. {
  544.         if(!(roamer->isminion && (roamer->data == &mons[PM_ALIGNED_PRIEST] ||
  545.                   roamer->data == &mons[PM_ANGEL])))
  546.             return;
  547.  
  548.         if(EPRI(roamer)->shralign != u.ualign.type) {
  549.         roamer->mpeaceful = roamer->mtame = 0;
  550.         set_malign(roamer);
  551.     }
  552.     newsym(roamer->mx, roamer->my);
  553. }
  554.  
  555. boolean
  556. in_your_sanctuary(x, y)
  557. xchar x, y;
  558. {
  559.     register char roomno;
  560.     register struct monst *priest;
  561.  
  562.     if ((u.ualign.record < -5) || !(roomno = temple_occupied(u.urooms)) ||
  563.         (roomno != *in_rooms(x, y, TEMPLE)) ||
  564.         !(priest = findpriest(roomno)))
  565.         return(FALSE);
  566.     return((boolean)(has_shrine(priest) && p_coaligned(priest) && priest->mpeaceful));
  567. }
  568.  
  569. void
  570. ghod_hitsu(priest)     /* when attacking "priest" in his temple */
  571. struct monst *priest;
  572. {
  573.     int x, y, ax, ay, roomno = (int)temple_occupied(u.urooms);
  574.     struct mkroom *troom;
  575.  
  576.     if (!roomno || !has_shrine(priest))
  577.         return;
  578.  
  579.     ax = x = EPRI(priest)->shrpos.x;
  580.     ay = y = EPRI(priest)->shrpos.y;
  581.     troom = &rooms[roomno - ROOMOFFSET];
  582.  
  583.     if((u.ux == x && u.uy == y) || !linedup(u.ux, u.uy, x, y)) {
  584.         if(IS_DOOR(levl[u.ux][u.uy].typ)) {
  585.  
  586.         if(u.ux == troom->lx - 1) {
  587.             x = troom->hx;
  588.             y = u.uy;
  589.         } else if(u.ux == troom->hx + 1) {
  590.             x = troom->lx;
  591.             y = u.uy;
  592.         } else if(u.uy == troom->ly - 1) {
  593.             x = u.ux;
  594.             y = troom->hy;
  595.         } else if(u.uy == troom->hy + 1) {
  596.             x = u.ux;
  597.             y = troom->ly;
  598.         }
  599.         } else {
  600.         switch(rn2(4)) {
  601.         case 0:  x = u.ux; y = troom->ly; break;
  602.         case 1:  x = u.ux; y = troom->hy; break;
  603.         case 2:  x = troom->lx; y = u.uy; break;
  604.         default: x = troom->hx; y = u.uy; break;
  605.         }
  606.         }
  607.         if(!linedup(u.ux, u.uy, x, y)) return;
  608.     }
  609.  
  610.     switch(rn2(3)) {
  611.     case 0:
  612.         pline("%s roars in anger:  \"Thou shalt suffer!\"",
  613.             a_gname_at(ax, ay));
  614.         break;
  615.     case 1:
  616.         pline("%s voice booms:  \"How darest thou harm my servant!\"",
  617.             s_suffix(a_gname_at(ax, ay)));
  618.         break;
  619.     default:
  620.         pline("%s roars:  \"Thou dost profane my shrine!\"",
  621.             a_gname_at(ax, ay));
  622.         break;
  623.     }
  624.  
  625.     buzz(-10-(AD_ELEC-1), 6, x, y, sgn(tbx), sgn(tby)); /* bolt of lightning */
  626.     exercise(A_WIS, FALSE);
  627. }
  628.  
  629. void
  630. angry_priest()
  631. {
  632.     register struct monst *priest;
  633.  
  634.     if ((priest = findpriest(temple_occupied(u.urooms))) != 0)
  635.         wakeup(priest);
  636. }
  637.  
  638. /*
  639.  * When saving bones, find priests that aren't on their shrine level,
  640.  * and remove them.   This avoids big problems when restoring bones.
  641.  */
  642. void
  643. clearpriests()
  644. {
  645.     register struct monst *mtmp, *mtmp2;
  646.  
  647.     for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  648.     mtmp2 = mtmp->nmon;
  649.     if (mtmp->ispriest && !on_level(&(EPRI(mtmp)->shrlevel), &u.uz))
  650.         mongone(mtmp);
  651.     }
  652. }
  653.  
  654. /* munge priest-specific structure when restoring -dlc */
  655. void
  656. restpriest(mtmp, ghostly)
  657. register struct monst *mtmp;
  658. boolean ghostly;
  659. {
  660.     if(u.uz.dlevel) {
  661.     if (ghostly)
  662.         assign_level(&(EPRI(mtmp)->shrlevel), &u.uz);
  663.     }
  664. }
  665.  
  666. #endif /* OVLB */
  667.  
  668. /*priest.c*/
  669.